#ifndef _g711toaac_h_
#define _g711toaac_h_

#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "../lib/libfaac/faac/frame.h"
// #include "../inc/faaccfg.h"


#define G711_ONE_LEN 160
#define FAAC_CFG_VERSION 104

/* MPEG ID's */
#define MPEG2 1
#define MPEG4 0

/* AAC object types */
#define MAIN 1
#define LOW  2
#define SSR  3
#define LTP  4

/* Input Formats */
#define FAAC_INPUT_NULL    0
#define FAAC_INPUT_16BIT   1
#define FAAC_INPUT_24BIT   2
#define FAAC_INPUT_32BIT   3
#define FAAC_INPUT_FLOAT   4

#define SHORTCTL_NORMAL    0
#define SHORTCTL_NOSHORT   1
#define SHORTCTL_NOLONG    2

typedef struct _g711param
{
	unsigned char ucRateBits;
}G711Param;

typedef struct _g726param
{
	unsigned char ucRateBits;//Rate16kBits Rate24kBits Rate32kBits Rate40kBits
}G726Param;

typedef struct _initParam
{ 
	unsigned char	ucAudioCodec;			// Law_uLaw  Law_ALaw Law_PCM16 Law_G726   源数据的编码类型
	unsigned char	ucAudioChannel;			//1      通道
	unsigned int	u32AudioSamplerate;		//8000   采样率
	unsigned int	u32PCMBitSize;			//16     采样位数
	union
	{
		G711Param g711param;
		G726Param g726param;
	};

}InitParam;

///* Audio Codec */
enum Law
{
	Law_ULaw	=	0, 		/**< U law */
	Law_ALaw	=	1, 		/**< A law */
	Law_PCM16	=	2, 		/**< 16 bit uniform PCM values. ԭʼ pcm ���� */  
	Law_G726	=	3		/**< G726 */
};

///* Rate Bits */
enum Rate
{
	Rate16kBits=2,	/**< 16k bits per second (2 bits per ADPCM sample) */
	Rate24kBits=3,	/**< 24k bits per second (3 bits per ADPCM sample) */
	Rate32kBits=4,	/**< 32k bits per second (4 bits per ADPCM sample) */
	Rate40kBits=5	/**< 40k bits per second (5 bits per ADPCM sample) */
};
enum INDATA
{
	FILETYPE,
	FRAMETYPE
};
enum G711Type
{
	G711a,
	G711u
};



typedef struct
{
    unsigned char *data_;
	int len_;
    int sumLen_;
}audio_buffer;

typedef struct
{
    unsigned int m_u32AudioCodec;
	unsigned int m_u32AudioSamplerate;
	unsigned int m_u32AudioChannel;

	unsigned int m_nPCMBitSize;   /* 采样位数 */

	InitParam m_initparam;
}InAudioInfo;
typedef struct
{
   int m_g7FrameSize;
   int (*Decode)(unsigned char* outbuf, unsigned int* outlen , unsigned char* inbuf, unsigned int inlen);
}IDecodeToPcm;


typedef struct
{
    void* hEncoder;    /* faac 编码句柄 */
	faacEncConfigurationPtr pConfiguration;

	unsigned int m_nPCMBitSize /*= 16*/;

	unsigned long m_nInputSamples /*= 0*/;

	unsigned long m_nMaxOutputBytes /*= 0*/;
}PcmToAac;

typedef struct
{
    int nRet;     /* 记录每次把 PCM 缓存区数据转换成 AAC 后的大小*/
    int nTmp;     /* 每次将解码帧写入 PCM 缓存区上的时候，最后总有一帧写不完的，记录那一帧没写完的还有多少没写完 */
    int nCount;  /* 记录 PCM 缓存区已经存入了多少*/
    int nStatus;   /* 记录 PCM 缓存区内存够不够用 */
    int nPCMRead;   /* 每次解码的长度 */
    // PCM 缓存区
    int m_nPCMBufferSize;   /* 解码后的数据缓存区大小 */
    unsigned char *m_pbPCMBuffer;    /* 存解码后的数据的 */
    // AAC 缓存区
    unsigned long m_nMaxOutputBytes;  /* AAC 缓存区大小 */
    unsigned char *m_pbAACBuffer;
    // pcm 帧缓存区
    int m_nPCMSize;     /* 解码后的一帧数据的大小 */
    unsigned char *m_pbPCMTmpBuffer;   /* 存解码后的一帧PCM数据 */
    // g711帧缓存区
	unsigned char *m_pbG7FrameBuffer;   /* 存一帧没有解码的 G711 数据 */
	unsigned long m_nG7FrameBufferSize;

    audio_buffer *m_audio_buffer_;     // 存G711数据的 ；为了赛选一帧数据的
	InAudioInfo m_inAudioInfo;    // 音频数据的信息的
	IDecodeToPcm *m_pDecodeToPcm;     // 解码的 
	PcmToAac* m_pPCMToAAC;    // 编码的  
    
}G7ToAac;

int g711Decode(unsigned char* pout_buf, unsigned int* pout_len , unsigned char* pin_buf, unsigned int in_len);

unsigned short DecodeOneChar(unsigned char data);

int alaw2linear(unsigned char	a_val);

int aac_Encode(void* para,int32_t * pbPCMBuffer, unsigned int nPCMBufferSize, unsigned char * pbAACBuffer, unsigned int nMaxOutputBytes);

int g711_t_aac_decode(void * para,void * data,int len, unsigned char* outbuf, unsigned int* outlen );

// 按帧进行转码
int g711_t_aac_frame_decode(void * para,const unsigned char * inframe_data,const int infream_len,unsigned char *AacFrame_data,int *aac_len);


int  Easy_AACEncoder_Init(void * encodectx, int initType,int g711FrameLen);

int  Easy_AACEncoder_Encode(void* handle, unsigned char* inbuf, unsigned int inlen, unsigned char* outbuf, unsigned int* outlen);

void  Easy_AACEncoder_Release(void* handle);


/* g711 转换成 AAC 的接口*/
int g711_2_aac_test(const char *infile, const char * outfile);

int g711_2_aac_frame_init(void *para,int infream_len);
int g711_2_aac_frame(void *para,const unsigned char * inframe_data,const int infream_len,int inframe_type,unsigned char *AacFrame_data,int *aac_len);
int g711_2_aac_frame_uninit(void *para);

int g711_2_aac_frame_test(const char *infile, const char * outfile);




#endif 

